#include "canfestival.h"
#include "timerscfg.h"
unsigned int TimeCNT = 0;                   //时间计数
unsigned int NextTime = 0;                  //下一次触发时间计数
unsigned int TIMER_MAX_COUNT = 70000;       //最大时间计数
static TIMEVAL last_time_set = TIMEVAL_MAX; //上一次的时间计数
#if 0
void CAN1_RX0_IRQHandler(void)
{
    CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
    //接收处理
    m.cob_id = RxMessage.StdId;

    if (RxMessage.RTR == CAN_RTR_REMOTE)
        m.rtr = 1;
    else if (RxMessage.RTR == CAN_RTR_DATA)
        m.rtr = 0;
    m.len = RxMessage.DLC;
    for (i = 0; i < RxMessage.DLC; i++)
        m.data = RxMessage.Data;

    canDispatch(&TestSlave_Data, &m);
}
#endif
void CAN_Config(void)
{
#if 0
    /* CAN register init */
    CAN_DeInit(CAN1);
    CAN_DeInit(CAN2);
    CAN_StructInit(&CAN_InitStructure);

    /* CAN1 cell init */
    CAN_InitStructure.CAN_TTCM = DISABLE;
    CAN_InitStructure.CAN_ABOM = DISABLE;
    CAN_InitStructure.CAN_AWUM = DISABLE;
    CAN_InitStructure.CAN_NART = DISABLE;
    CAN_InitStructure.CAN_RFLM = DISABLE;
    CAN_InitStructure.CAN_TXFP = DISABLE;
    CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
    //Fpclk=72M/2/CAN_Prescaler
    //BitRate=Fpclk/((CAN_SJW+1)*((CAN_BS1+1)+(CAN_BS2+1)+1));
    //1M
    /*CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
  CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
  CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
  CAN_InitStructure.CAN_Prescaler = 4;*/
    //125K
    CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
    CAN_InitStructure.CAN_BS1 = CAN_BS1_8tq;
    CAN_InitStructure.CAN_BS2 = CAN_BS2_7tq;
    CAN_InitStructure.CAN_Prescaler = 18;

    CAN_Init(CAN1, &CAN_InitStructure);
    CAN_Init(CAN2, &CAN_InitStructure);

    /* CAN1 filter init */
    CAN_FilterInitStructure.CAN_FilterNumber = 0;
    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
    CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
    CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
    CAN_FilterInit(&CAN_FilterInitStructure);

    /* CAN2 filter init */
    CAN_FilterInitStructure.CAN_FilterNumber = 14;
    CAN_FilterInit(&CAN_FilterInitStructure);
#endif
}
unsigned char canSend(CAN_PORT notused, Message *m)
{
#if 0
    uint32_t i;
    CanTxMsg *ptx_msg = &TxMessage;
    ptx_msg->StdId = m->cob_id;

    if (m->rtr)
        ptx_msg->RTR = CAN_RTR_REMOTE;
    else
        ptx_msg->RTR = CAN_RTR_DATA;

    ptx_msg->IDE = CAN_ID_STD;
    ptx_msg->DLC = m->len;
    for (i = 0; i < m->len; i++)
        ptx_msg->Data = m->data;

    if (CAN_Transmit(CAN1, ptx_msg) == CAN_NO_MB)
    {
        return 0xff;
    }
    else
    {
        return 0x00;
    }
#endif
}
#if 0
static void TIM4_Configuration(void)
{
    /* 时钟及分频设置 */

    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    /* Time Base configuration */
    /* 72M / 72 = 1us */
    // 这个就是预分频系数，当由于为0时表示不分频所以要减1
    TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; //72000 - 1;
    //计数模式:向上计数
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    //这个就是自动装载的计数值，由于计数是从0开始的
    //TIM_TimeBaseStructure.TIM_Period =0xffff;//
    TIM_TimeBaseStructure.TIM_Period = 0x03e8; //1ms
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    //重新计数的起始值
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);

    // TIM IT enable
    TIM_ITConfig(TIM4, TIM_IT_CC1, ENABLE); //打开溢出中断

    // TIM enable counter
    TIM_Cmd(TIM4, ENABLE); //计数器使能，开始工作
}

static void NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);
    /* Enable the TIM4 global Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

static void RCC_Configuration(void)
{

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

    /* TIM4 clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

    /* clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
}

void TIM4_start(void)
{
    RCC_Configuration();

    /* configure TIM4 for remote and encoder */
    NVIC_Configuration();
    TIM4_Configuration();
}

void TIM4_IRQHandler(void)
{
    if (TIM_GetITStatus(TIM4, TIM_IT_CC1) != RESET)
    {
        //printf("enter tim4");
        TIM_ClearITPendingBit(TIM4, TIM_IT_CC1);
    }
    TimerForCan();
}
void timerForCan(void)
{
    TimeCNT++;
    if (TimeCNT >= TIMER_MAX_COUNT)
    {
        TimeCNT = 0;
    }
    if (TimeCNT == NextTime)
    {
        TimeDispatch();
    }
}
#endif
void setTimer(TIMEVAL value)
{
    NextTime = (TimeCNT + value) % TIMER_MAX_COUNT;
}

// Get the elapsed time since the last occured alarm //
TIMEVAL getElapsedTime(void)
{
    int ret = 0;
    ret = TimeCNT > last_time_set ? TimeCNT - last_time_set : TimeCNT + TIMER_MAX_COUNT - last_time_set;
    last_time_set = TimeCNT;
    return ret;
}

void TimerInit(void)
{
    // LARGE_INTEGER liDueTime;
    // liDueTime.QuadPart = 0;

    // InitializeCriticalSection(&CanFestival_mutex);

    // timer = CreateWaitableTimer(NULL, FALSE, NULL);
    // if(NULL == timer)
    // {
    //     printf("CreateWaitableTimer failed (%d)\n", GetLastError());
    // }

    // // Take first absolute time ref in milliseconds.
    // timebuffer = GetTickCount();
}

void TimerCleanup(void)
{
    // DeleteCriticalSection(&CanFestival_mutex);
}

void StopTimerLoop(TimerCallback_t exitfunction)
{
#if 0
	EnterMutex();
	exitfunction(NULL,0);
	LeaveMutex();

	stop_timer = 1;
	setTimer(0);
	if(WaitForSingleObject(timer_thread,1000) == WAIT_TIMEOUT)
	{
		TerminateThread(timer_thread, -1);
	}
	CloseHandle(timer);
	CloseHandle(timer_thread);
#endif
}
int canClose(CO_Data *d)
{
    int res = 0;

    // CANPort* port = (CANPort*)d->canHandle;
    // if(port){
    //     ((CANPort*)d->canHandle)->used = 0;

    //     res = m_canClose(port->fd);

    //     WaitReceiveTaskEnd(&port->receiveTask);

    //     d->canHandle = NULL;
    // }

    return res;
}

UNS8 UnLoadCanDriver(LIB_HANDLE handle)
{
    // #ifndef NOT_USE_DYNAMIC_LOADING
    // 	if(handle != NULL)
    // 	{
    // 		FreeLibrary(handle);
    // 		handle=NULL;
    // 		return 0;
    // 	}
    // 	return -1;
    // #else
    //   handle = NULL;
    //   return 0;
    // #endif //NOT_USE_DYNAMIC_LOADING
}

CAN_HANDLE canOpen(s_BOARD *board, CO_Data *d)
{
    // int i;
    // CAN_HANDLE fd0;

    //   /* Fix of multiple opening one data set, added by J.Fojtik. */
    // if(d->canHandle)
    // {
    //   canClose(d);
    // }

    // for(i=0; i < MAX_NB_CAN_PORTS; i++)
    // {
    // 	if(!canports[i].used)
    // 	break;
    // }

    // #ifndef NOT_USE_DYNAMIC_LOADING
    // if (m_canOpen == NULL)
    // {
    //    	fprintf(stderr,"CanOpen : Can Driver dll not loaded\n");
    //    	return NULL;
    // }
    // #endif

    // fd0 = m_canOpen(board);
    // if(fd0)
    // {
    // 	canports[i].used = 1;
    // 	canports[i].fd = fd0;
    // 	canports[i].d = d;
    // 	d->canHandle = (CAN_PORT)&canports[i];
    // 	CreateReceiveTask(&(canports[i]), &canports[i].receiveTask, (void *)canReceiveLoop);
    // 	return (CAN_PORT)&canports[i];
    // }
    // else
    // {
    // 	printf("CanOpen : Cannot open board {busname='%S',baudrate='%S'}\n",board->busname, board->baudrate);
    // 	return NULL;
    // }
}
void StartTimerLoop(TimerCallback_t _init_callback)
{
    // unsigned long timer_thread_id;
    // stop_timer = 0;
    // init_callback = _init_callback;
    // EnterMutex();
    // 	// At first, TimeDispatch will call init_callback.
    // SetAlarm(NULL, 0, init_callback, 0, 0);
    // LeaveMutex();
    // timer_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)TimerThreadLoop, NULL, 0, &timer_thread_id);
}

void EnterMutex(void)
{
    // EnterCriticalSection(&CanFestival_mutex);
}

void LeaveMutex(void)
{
    // LeaveCriticalSection(&CanFestival_mutex);
}

LIB_HANDLE LoadCanDriver(char * driver_name)
{
    // driver module handle
    LIB_HANDLE handle = NULL;

// #ifndef NOT_USE_DYNAMIC_LOADING
//     handle = LoadLibrary(driver_name);

//     if (!handle)
//     {
//         fprintf (stderr, "LoadLibrary error : %d\n", GetLastError());
//         return NULL;
//     }

//     m_canReceive = (CANRECEIVE_DRIVER_PROC)GetProcAddress(handle, myTEXT("canReceive_driver"));
//     m_canSend = (CANSEND_DRIVER_PROC)GetProcAddress(handle, myTEXT("canSend_driver"));
//     m_canOpen = (CANOPEN_DRIVER_PROC)GetProcAddress(handle, myTEXT("canOpen_driver"));
//     m_canClose = (CANCLOSE_DRIVER_PROC)GetProcAddress(handle, myTEXT("canClose_driver"));
//     m_canChangeBaudRate = (CANCHANGEBAUDRATE_DRIVER_PROC)GetProcAddress(handle, myTEXT("canChangeBaudRate_driver"));

//     if(m_canReceive==NULL || m_canSend==NULL || m_canOpen==NULL || m_canClose==NULL || m_canChangeBaudRate==NULL)
//     {
//         m_canReceive = NULL;
//         m_canSend = NULL;
//         m_canOpen = NULL;
//         m_canClose = NULL;
//         m_canChangeBaudRate = NULL;
//         FreeLibrary(handle);
//         fprintf (stderr, "GetProc error : %d\n", GetLastError());
//         return NULL;
//     }
// #else
//     //compiled in...
//     handle = 1; //TODO: remove this hack

//     m_canReceive = canReceive_driver;
//     m_canSend = canSend_driver;
//     m_canOpen = canOpen_driver;
//     m_canClose = canClose_driver;
//     m_canChangeBaudRate = canChangeBaudRate_driver;
// #endif


    return handle;
}